package com.lwl.concurrency.forkjoin;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

/**
 * Created by liwenlong on 2018/1/15 14:02
 */
public class FolderProcessor extends RecursiveTask<List<String>> {
    private static final long serialVersionUID = 9179067217696803278L;
    private String path;
    private String extension;

    public FolderProcessor(String path, String extension) {
        this.path = path;
        this.extension = extension;
    }

    @Override
    protected List<String> compute() {
        System.out.println("compute 被调用");
        List<String> list = new ArrayList<>();
        List<FolderProcessor> tasks = new ArrayList<>();
        File dir = new File(path);
        File[] contents = dir.listFiles();
        if (contents != null) {
            for (File file : contents) {
                if (file.isDirectory()) {
                    FolderProcessor task = new FolderProcessor(file.getAbsolutePath(), extension);
                    task.fork();
                    tasks.add(task);
                } else {
                    if (file.getName().endsWith(extension)) {
                        list.add(file.getAbsolutePath());
                    }
                }
            }
            if (tasks.size() > 50) {
                System.out.printf("%s: %d tasks ran.\n", dir.getAbsolutePath(), tasks.size());
            }
            addResultsFromTasks(list, tasks);
        }
        return list;
    }

    private void addResultsFromTasks(List<String> list, List<FolderProcessor> tasks) {
        for (FolderProcessor item : tasks) {
            list.addAll(item.join());
        }
    }

    public static void main(String[] args) {
        //使用默认构造器创建ForkJoinPool。
        ForkJoinPool pool = new ForkJoinPool();
        //创建3个FolderProcessor任务。用不同的文件夹路径初始化每个任务。
        FolderProcessor system = new FolderProcessor("E:\\renbao", "txt");
        //FolderProcessor apps = new FolderProcessor("C:\\Program Files", "log");
        //FolderProcessor documents = new FolderProcessor("C:\\Documents And Settings", "log");
        //在池中使用execute()方法执行这3个任务。
        pool.execute(system);
        //pool.execute(apps);
        //pool.execute(documents);
        //将关于池每秒的状态信息写入到控制台，直到这3个任务完成它们的执行。
        do {
            System.out.printf("******************************************\n");
            System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
            System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount());
            System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount());
            System.out.printf("Main: Steal Count: %d\n", pool.getStealCount());
            System.out.printf("******************************************\n");
            /*try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        } while ((!system.isDone()));
        //使用shutdown()方法关闭ForkJoinPool。
        pool.shutdown();
        //将每个任务产生的结果数量写入到控制台。
        List<String> results = system.join();
        System.out.printf("System: %d files found.\n", results.size());
        for (String result : results) {
            System.out.println(result);
        }


    }

}
